package com.bite.forum.services.impl;

import com.bite.forum.common.AppResult;
import com.bite.forum.common.ResultCode;
import com.bite.forum.dao.UserMapper;
import com.bite.forum.exception.ApplicationException;
import com.bite.forum.model.User;
import com.bite.forum.services.IUserService;
import com.bite.forum.utils.MD5Util;
import com.bite.forum.utils.StringUtil;
import com.bite.forum.utils.UUIDUtil;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class UserServiceImpl implements IUserService {
    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Resource
    private UserMapper userMapper;

    //非空校验
    @Override
    public void craeteNormalUser(User user) {
        //判断用户对象是否为空，用户名、密码、昵称、盐是否为空
        if (user == null || StringUtil.isEmpty(user.getUsername())
                || StringUtil.isEmpty(user.getPassword()) || StringUtil.isEmpty(user.getNickname())
                || StringUtil.isEmpty(user.getSalt())) {
            //记录警告日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        //按用户名查询用户信息
        User newUser = userMapper.selectUserByUserName(user.getUsername());
        //如果用户已存在，抛出异常
        if (newUser != null) {
            log.info(ResultCode.FAILED_USER_EXISTS.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_EXISTS));
        }

        //设置用户性别、文章数量、是否管理员、状态、删除状态、创建时间、更新时间
        user.setGender((byte) 2);
        user.setArticleCount(0);
        user.setIsAdmin((byte) 0);
        user.setState((byte) 0);
        user.setDeleteState((byte) 0);
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);

        //写入数据库
        int row = userMapper.insertSelective(user);
        //如果插入失败，抛出异常
        if (row != 1) {
            log.info(ResultCode.FAILED_CREATE.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_CREATE));
        }

        //记录成功日志
        log.info("用户" + ResultCode.SUCCESS.toString() + "username = " + user.getUsername());
    }

    @Override
    public User selectUserByUserName(String username) {
        //非空校验
        if (StringUtil.isEmpty(username)) {
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        return userMapper.selectUserByUserName(username);
    }

    /*@Override
    public User login(String username, String password) {
        //非空校验
        if (StringUtil.isEmpty(username) || StringUtil.isEmpty(password)) {
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        //根据用户名查询用户
        User user = selectUserByUserName(username);
        if (user == null) {
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        //获取用户盐值
        String salt = user.getSalt();
        //对密码进行加密
        String passwordMd5 = MD5Util.md5Salt(password,salt);
        //判断加密后的密码是否与数据库中的密码一致
        if(!passwordMd5.equals(user.getPassword())){
            log.info(ResultCode.FAILED_LOGIN + ",密码错误，username = " + username);
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN));
        }

        return user;
    }*/

    @Override
    public User login(String username, String password) {
        log.info("进入登录逻辑，username={}, password=****", username);

        // 非空校验
        if (StringUtil.isEmpty(username) || StringUtil.isEmpty(password)) {
            log.warn("参数校验失败：用户名为空或密码为空");
            throw new ApplicationException(ResultCode.FAILED_PARAMS_VALIDATE.toString());
        }

        log.info("查询用户：username={}", username);
        User user = userMapper.selectUserByUserName(username);
        if (user == null) {
            log.warn("用户不存在：username={}", username);
            throw new ApplicationException(ResultCode.FAILED_USER_NOT_EXISTS.toString());
        }

        log.info("开始验证密码，username={}", username);
        String passwordMd5 = MD5Util.md5Salt(password, user.getSalt());
        if (!passwordMd5.equals(user.getPassword())) {
            log.warn("密码错误，username={}", username);
            throw new ApplicationException(ResultCode.FAILED_LOGIN + ",密码错误，username = " + username);
        }

        log.info("登录成功，username={}", username);
        return user;
    }

    @Override
    // 根据id查询用户
    public User selectById(Long id) {
        // 如果id为空
        if(id == null){
            // 记录日志
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 根据id查询用户
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public void addOneArticleCountById(Long id) {
        // 判断id是否为空或小于等于0
        if(id == null || id <= 0){
            // 记录警告日志
            log.warn(ResultCode.FAILED_USER_ARTICLE_COUNT.toString() + "，user id = " + id);
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_ARTICLE_COUNT));
        }
        // 根据id查询用户
        User user = userMapper.selectByPrimaryKey(id);
        // 判断用户是否存在
        if(user == null){
            // 记录警告日志
            log.warn(ResultCode.ERROR_IS_NULL.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.ERROR_IS_NULL));
        }

        // 创建新用户对象
        User newUser = new User();
        // 设置用户id
        newUser.setId(user.getId());
        // 设置用户文章数量加1
        newUser.setArticleCount(user.getArticleCount() + 1);
        // 更新用户信息
        int row = userMapper.updateByPrimaryKeySelective(newUser);
        // 判断受影响行数是否为1
        if(row != 1){
            // 记录警告日志
            log.warn(ResultCode.FAILED_USER_ARTICLE_COUNT+ "受影响行数" + row);
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_ARTICLE_COUNT));
        }
    }

    @Override
    public void subOneArticleCountById(Long id) {
        // 判断id是否为空或小于等于0
        if(id == null || id <= 0){
            // 记录警告日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        // 根据id查询Board对象
        User user = userMapper.selectByPrimaryKey(id);
        // 判断User对象是否为空
        if(user == null){
            // 记录警告日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS + "，board id = " + id);
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        User newUser = new User();
        newUser.setId(user.getId());
        newUser.setArticleCount(user.getArticleCount() - 1);
        if(newUser.getArticleCount() < 0){
            newUser.setArticleCount(0);
        }
        userMapper.updateByPrimaryKeySelective(newUser);
    }

    @Override
    public void modifyInfo(User user) {
        // 判断用户是否为空，用户ID是否为空或小于等于0
        if(user == null || user.getId() == null || user.getId() <= 0){
            // 记录警告日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        // 根据用户ID查询用户信息
        User oldUser = userMapper.selectByPrimaryKey(user.getId());
        // 判断用户信息是否存在
        if(oldUser == null){
            // 记录警告日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        // 定义一个标志位，用于判断是否有需要更新的字段
        boolean flag = false;
        // 创建一个新用户对象，用于更新用户信息
        User updateUser = new User();
        // 设置用户ID
        updateUser.setId(user.getId());
        // 判断用户名是否为空，且与旧用户名不同
        if(!StringUtil.isEmpty(user.getUsername()) && !oldUser.getUsername().equals(user.getUsername())){
            // 根据用户名查询用户信息
            User checkUser = userMapper.selectUserByUserName(user.getUsername());
            // 判断用户信息是否存在
            if(checkUser != null){
                // 记录警告日志
                log.warn(ResultCode.FAILED_USER_UPDATE_F.toString());
                // 抛出异常
                throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_UPDATE_F));
            }
            // 设置用户名
            updateUser.setUsername(user.getUsername());
            // 标志位设为true
            flag = true;
        }

        // 判断昵称是否为空，且与旧昵称不同
        if(!StringUtil.isEmpty(user.getNickname()) && !oldUser.getNickname().equals(user.getNickname())){
            // 设置昵称
            updateUser.setNickname(user.getNickname());
            // 标志位设为true
            flag = true;
        }

        // 判断性别是否为空，且与旧性别不同
        if(user.getGender() != null && !oldUser.getGender().equals(user.getGender())){
            // 设置性别
            updateUser.setGender(user.getGender());
            // 合法性校验
            if (updateUser.getGender() > 2 || updateUser.getGender() < 0) {
                updateUser.setGender((byte) 2);
            }
            // 标志位设为true
            flag = true;
        }

        // 判断邮箱是否为空，且与旧邮箱不同
        if(oldUser.getEmail() == null || (!StringUtil.isEmpty(user.getEmail()) && !oldUser.getEmail().equals(user.getEmail()))){
            // 设置邮箱
            updateUser.setEmail(user.getEmail());
            // 标志位设为true
            flag = true;
        }

        // 判断备注是否为空，且与旧备注不同
        if(oldUser.getRemark() == null || (!StringUtil.isEmpty(user.getRemark()) && !oldUser.getRemark().equals(user.getRemark()))){
            // 设置备注
            updateUser.setRemark(user.getRemark());
            // 标志位设为true
            flag = true;
        }

        // 判断电话号码是否为空，且与旧电话号码不同
        if(oldUser.getPhoneNum() == null || (!StringUtil.isEmpty(user.getPhoneNum()) && !oldUser.getPhoneNum().equals(user.getPhoneNum()))){
            // 设置电话号码
            updateUser.setPhoneNum(user.getPhoneNum());
            // 标志位设为true
            flag = true;
        }

        // 判断标志位是否为false，即没有需要更新的字段
        if(!flag){
            // 记录警告日志
            log.info(ResultCode.FAILED_USER_UPDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_UPDATE));
        }

        Date date = new Date();
        updateUser.setUpdateTime(date);

        // 更新用户信息
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        // 判断受影响行数是否为1
        if(row != 1){
            // 记录警告日志
            log.warn(ResultCode.FAILED_USER_ARTICLE_COUNT+ "受影响行数" + row);
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_ARTICLE_COUNT));
        }
        // 记录信息修改成功日志
        log.info("信息修改成功");
    }

    @Override
    public void modifyPassword(Long id, String newPassword, String oldPassword) {
        if(id == null || id <= 0 || StringUtil.isEmpty(newPassword) || StringUtil.isEmpty(oldPassword)){
            // 记录警告日志
            log.warn(ResultCode.FAILED_USER_UPDATE_F.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_UPDATE_F));
        }

        User user = userMapper.selectByPrimaryKey(id);

        if(user == null || user.getDeleteState() == 1){
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        String oldPwd = MD5Util.md5Salt(oldPassword,user.getSalt());
        if(!oldPwd.equalsIgnoreCase(user.getPassword())){
            log.warn("原密码错误！");
            throw new ApplicationException("原密码错误！");
        }

        String newSalt = UUIDUtil.UUID_32();
        String updatePassword = MD5Util.md5Salt(newPassword,newSalt);

        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setSalt(newSalt);
        updateUser.setPassword(updatePassword);
        Date date = new Date();
        updateUser.setUpdateTime(date);

        int row = userMapper.updateByPrimaryKeySelective(updateUser);

        if(row != 1){
            // 记录警告日志
            log.warn(ResultCode.FAILED_USER_ARTICLE_COUNT+ "受影响行数" + row);
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_ARTICLE_COUNT));
        }

        // 记录信息修改成功日志
        log.info("信息修改成功");
    }
}
